package com.zzyl.nursing.service.impl;

import java.util.*;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.json.JSON;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.aliyun.iot20180120.Client;
import com.aliyun.iot20180120.models.*;
import com.zzyl.common.constant.CacheConstants;
import com.zzyl.common.core.domain.R;
import com.zzyl.common.exception.ServiceException;
import com.zzyl.common.utils.DateUtils;
import com.zzyl.common.utils.StringUtils;
import com.zzyl.framework.config.properties.AliIoTConfigProperties;
import com.zzyl.nursing.domain.DeviceDto;
import com.zzyl.nursing.vo.DeviceVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import com.zzyl.nursing.mapper.DeviceMapper;
import com.zzyl.nursing.domain.Device;
import com.zzyl.nursing.service.IDeviceService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

import java.util.stream.Collectors;

/**
 * 智能设备管理Service业务层处理
 *
 * @author Kelvin
 * @date 2025-01-04
 */
@Service
public class DeviceServiceImpl extends ServiceImpl<DeviceMapper, Device> implements IDeviceService {
    @Autowired
    private DeviceMapper deviceMapper;

    @Autowired
    private Client client;

    @Autowired
    private AliIoTConfigProperties aliIoTConfigProperties;

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @Qualifier("redisTemplate")
    @Autowired
    private RedisTemplate redisTemplate;

    /**
     * 查询智能设备管理
     *
     * @param id 智能设备管理主键
     * @return 智能设备管理
     */
    @Override
    public Device selectDeviceById(Long id) {
        return getById(id);
    }

    /**
     * 查询智能设备管理列表
     *
     * @param device 智能设备管理
     * @return 智能设备管理
     */
    @Override
    public List<Device> selectDeviceList(Device device) {
        return deviceMapper.selectDeviceList(device);
    }

    /**
     * 新增智能设备管理
     *
     * @param device 智能设备管理
     * @return 结果
     */
    @Override
    public int insertDevice(Device device) {
        return save(device) ? 1 : 0;
    }

    /**
     * 修改智能设备管理
     *
     * @param device 智能设备管理
     * @return 结果
     */
    @Override
    public int updateDevice(Device device) {
        return updateById(device) ? 1 : 0;
    }

    /**
     * 批量删除智能设备管理
     *
     * @param ids 需要删除的智能设备管理主键
     * @return 结果
     */
    @Override
    public int deleteDeviceByIds(Long[] ids) {
        return removeByIds(Arrays.asList(ids)) ? 1 : 0;
    }

    /**
     * 删除智能设备管理信息
     *
     * @param id 智能设备管理主键
     * @return 结果
     */
    @Override
    public int deleteDeviceById(Long id) {
        return removeById(id) ? 1 : 0;
    }

    @Override
    public List<Map<String, String>> getProductList() {

        String jsonStr = stringRedisTemplate.opsForValue().get(CacheConstants.IOT_PRODUCT_LIST_ALL);
        if (StringUtils.isEmpty(jsonStr)) {
            return Collections.emptyList();
        }

        return JSONUtil.toList(jsonStr, ArrayList.class).stream()
                .map(item -> {
                    //                    String[] split1 = Objects.toString(item.get(item.size()-2)).split("[=|\"]");
                    //                    String[] split2 = Objects.toString(item.get(item.size()-1)).split("[=|\"]");
                    String[] split = item.get(item.size() - 1).toString().split("=");
                    String[] split1 = item.get(item.size() - 2).toString().split("=");

                    Map<String, String> map = new HashMap<>();
                    map.put("productKey", split1[1]);
                    map.put("productName", split[1]);

                    return map;
                }).collect(Collectors.toList());
    }

    @Override
    public void syncProductList() {
        QueryProductListRequest queryProductListRequest = new QueryProductListRequest();
        // 分页条件
        queryProductListRequest.setPageSize(10);
        queryProductListRequest.setCurrentPage(1);
        // 公共实例
        queryProductListRequest.setIotInstanceId(aliIoTConfigProperties.getIotInstanceId());
        // 查询公共实例下的所有产品
        QueryProductListResponse queryProductListResponse = null;
        try {
            queryProductListResponse = client.queryProductList(queryProductListRequest);
        } catch (Exception e) {
            throw new ServiceException("物联网接口 - 查询产品，同步失败");
        }

        //存到redis缓存
        List<QueryProductListResponseBody.QueryProductListResponseBodyDataListProductInfo> productInfo = queryProductListResponse.getBody().getData().getList().getProductInfo();
        stringRedisTemplate.opsForValue().set(CacheConstants.IOT_PRODUCT_LIST_ALL, JSONUtil.toJsonStr(productInfo));

    }

    @Override
    public void registerDevice(DeviceDto deviceDto) {
        //1.查询设备是否重复
        Long count = lambdaQuery().eq(Device::getDeviceName, deviceDto.getDeviceName()).count();
        if (count > 0) {
            throw new ServiceException("设备名称已经存在");
        }
        //2.IOT新增设备
        String iotId = addRemoteDevice(deviceDto);
        //3.查询产品 设置产品名称到设备对象
        Device device = BeanUtil.toBean(deviceDto, Device.class);
        device.setIotId(iotId);

        setProductName(device);
        //4.位置类型是否是0
        if (ObjectUtil.equal(deviceDto.getBindingLocation(), 0)) {
            device.setPhysicalLocationType(-1);
        }
        //5.保存到数据库是否成功
        try {
            device.setHaveEntranceGuard(0);
            save(device);
        } catch (Exception e) {
            log.error("新增失败");
            deleteIotDevice(device);
            throw new ServiceException("新增设备失败");
        }

        //6.如果保存失败要删除IOT的设备

    }

    @Override
    public DeviceVo queryDeviceDetail(DeviceDto deviceDto) {
        Device device = lambdaQuery().eq(Device::getIotId, deviceDto.getIotId()).one();
        DeviceVo vo = BeanUtil.toBean(device, DeviceVo.class);

        //Iot平台
        setIotDeviceDetail(vo);

        return vo;
    }

    @Override
    public R queryThingModelPublished(QueryThingModelPublishedRequest request) {
        request.setIotInstanceId(aliIoTConfigProperties.getIotInstanceId());
        try {
            QueryThingModelPublishedResponse queryThingModelPublishedResponse = client.queryThingModelPublished(request);
            if (queryThingModelPublishedResponse.getBody().success) {
                return R.ok(queryThingModelPublishedResponse.getBody().getData());
            }
        } catch (Exception e) {
            log.error("查询发布的无模型失败", e);
        }
        throw new ServiceException("查询发布的无模型失败");

    }

    @Override
    public R queryDevicePropertyStatus(QueryDevicePropertyStatusRequest request) {
        request.setIotInstanceId(aliIoTConfigProperties.getIotInstanceId());
        try {
            QueryDevicePropertyStatusResponse queryDevicePropertyStatusResponse = client.queryDevicePropertyStatus(request);
            if (queryDevicePropertyStatusResponse.getBody().success) {
                return R.ok(queryDevicePropertyStatusResponse.getBody().getData());
            }
        } catch (Exception e) {
            log.error("查询设备属性状态失败",e);
        }
        throw new ServiceException("查询设备属性状态失败");
    }

    private void setIotDeviceDetail(DeviceVo vo) {
        QueryDeviceDetailRequest queryDeviceDetailRequest = new QueryDeviceDetailRequest();
        queryDeviceDetailRequest.setIotId(vo.getIotId());
        queryDeviceDetailRequest.setIotInstanceId(aliIoTConfigProperties.getIotInstanceId());
        queryDeviceDetailRequest.setProductKey(vo.getProductKey());

        try {
            QueryDeviceDetailResponse queryDeviceDetailResponse = client.queryDeviceDetail(queryDeviceDetailRequest);
            if (queryDeviceDetailResponse.getBody().success) {
                BeanUtil.copyProperties(queryDeviceDetailResponse.getBody().getData(), vo);
            }
        } catch (Exception e) {
            log.error("查询Iot设备详情失败", e);
            throw new ServiceException("查询Iot设备详情失败");
        }

    }

    private void deleteIotDevice(Device device) {

        DeleteDeviceRequest deleteDeviceRequest = new DeleteDeviceRequest();
        deleteDeviceRequest.setIotInstanceId(aliIoTConfigProperties.getIotInstanceId());
        deleteDeviceRequest.setProductKey(device.getProductKey());
        deleteDeviceRequest.setIotId(device.getIotId());

        try {
            DeleteDeviceResponse deleteDeviceResponse = client.deleteDevice(deleteDeviceRequest);
            if (deleteDeviceResponse.getBody().success) {
                return;
            }
        } catch (Exception e) {
            log.error("IOT删除设备失败", e);
        }
        throw new ServiceException("IOT删除设备失败");


    }

    private void setProductName(Device device) {
        List<Map<String, String>> productList = getProductList();
        productList.stream()
                .filter(item -> item.containsValue(device.getProductKey()))
                .findFirst().ifPresent(obj -> device.setProductName(obj.get("productName")));
        //        for (Map<String, String> ssm : productList) {
        //            if(ssm.containsValue(device.getProductName())){
        //                device.setProductName(ssm.get("productName"));
        //            }
        //        }
    }

    private String addRemoteDevice(DeviceDto deviceDto) {
        RegisterDeviceRequest registerDeviceRequest = new RegisterDeviceRequest();
        registerDeviceRequest.setIotInstanceId(aliIoTConfigProperties.getIotInstanceId());
        registerDeviceRequest.setDeviceName(deviceDto.getDeviceName());
        registerDeviceRequest.setNickname(deviceDto.getNickname());
        registerDeviceRequest.setProductKey(deviceDto.getProductKey());

        try {
            RegisterDeviceResponse registerDeviceResponse = client.registerDevice(registerDeviceRequest);
            if (registerDeviceResponse.getBody().getSuccess()) {
                String iotId = registerDeviceResponse.getBody().getData().getIotId();
                return iotId;

            }

        } catch (Exception e) {
            log.error("IOT新增设备失败");
        }
        throw new ServiceException("添加设备失败");


    }
}